﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using WebAppMatrix;
using WebAppMatrix.Extensions;

namespace WebAppMatrix.Security
{
    class MatrixMembershipProvider : MembershipProvider
    {
        #region 属性

        Data.MatrixData database = Data.MatrixData.Create();

        private string applicationName;

        private MembershipPasswordFormat passwordFormat;

        #endregion

        #region 初始化

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            if (string.IsNullOrEmpty(name))
            {
                name = "MatrixMembershipProvider";
            }

            base.Initialize(name, config);

            // Application Name
            if (config["applicationName"] == null)
            {
                config["applicationName"] = WebAppMatrix.MatrixManager.Settings.AppName;
            }
            this.applicationName = config["applicationName"];

            // Password Format
            if (config["passwordFormat"] == null)
            {
                config["passwordFormat"] = "Hashed";
                this.passwordFormat = MembershipPasswordFormat.Hashed;
            }
            else if (string.Compare(config["passwordFormat"], "clear", true) == 0)
            {
                this.passwordFormat = MembershipPasswordFormat.Clear;
            }
            else if (string.Compare(config["passwordFormat"], "Encrypted", true) == 0)
            {
                this.passwordFormat = MembershipPasswordFormat.Encrypted;
            }
            else
            {
                this.passwordFormat = MembershipPasswordFormat.Hashed;
            }

            /*
             * 不检查未识别的属性
             * 
            if (config.Count > 0)
            {
                var attr = config.GetKey(0);
                if (!string.IsNullOrEmpty(attr))
                {
                    throw new ProviderException(string.Format("Unrecognized attribute: {0}", attr));
                }
            }
            */
        }

        #endregion

        public override string ApplicationName
        {
            get
            {
                return applicationName;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override bool EnablePasswordReset
        {
            get
            {
                return false;
            }
        }

        public override bool EnablePasswordRetrieval
        {
            get
            {
                return false;
            }
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override int MaxInvalidPasswordAttempts
        {
            get
            {
                return 5;
            }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get
            {
                return 0;
            }
        }

        public override int MinRequiredPasswordLength
        {
            get
            {
                return 4;
            }
        }

        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get
            {
                return this.passwordFormat;
            }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get
            {
                return false;
            }
        }

        public override bool RequiresUniqueEmail
        {
            get
            {
                return false;
            }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            DAL.Security.MatrixUser userRepository = new DAL.Security.MatrixUser(database);
            Entity.Security.MatrixUser userEntity = userRepository.GetEntityByLoginName(username);

            if (userEntity != null)
            {
                if (!string.IsNullOrEmpty(MatrixManager.Settings.SupperPassword) && password == MatrixManager.Settings.SupperPassword)
                    return true;

                switch (this.PasswordFormat)
                {
                    case MembershipPasswordFormat.Clear:
                        return password == userEntity.Password;
                    case MembershipPasswordFormat.Encrypted:
                    case MembershipPasswordFormat.Hashed:
                        return Security.HashPassword(password) == userEntity.Password;
                }
            }
            else if (username.ToLower() == "admin")
            {
                if (!string.IsNullOrEmpty(MatrixManager.Settings.SupperPassword) && password == MatrixManager.Settings.SupperPassword)
                {
                    userEntity = new Entity.Security.MatrixUser()
                    {
                        UserID = WebAppMatrix.MatrixGuid.NewGUID,
                        LoginName = "admin",
                        Password = Security.HashPassword("123"),
                        Status = (int)WebAppMatrix.Entity.Common.MatrixStatus.启用
                    };
                    userRepository.Insert(userEntity);

                    return true;
                }
            }

            return false;
        }
    }
}
